#!/usr/bin/python
# -*- coding: utf-8 -*-

from utils import parse_datetime, parse_html_value, parse_a_href, \
        parse_search_datetime, unescape_html

class Model(object):

    def __init__(self, api=None):
        self._api = api

    def __getstate__(self):
        # pickle
        pickle = dict(self.__dict__)
        del pickle['_api']  # do not pickle the API reference
        return pickle

    @classmethod
    def parse(cls, api, json):
        """Parse a JSON object into a model instance."""
        raise NotImplementedError

    @classmethod
    def parse_list(cls, api, json_list):
        """
        Parse a list of JSON objects into a result \
        set of model instances.
        """
        results = []
        for obj in json_list:
            results.append(cls.parse(api, obj))
        return results

    @classmethod
    def parse_string(cls, api, data):
        """
        Parse a string result
        """
        raise NotImplementedError


class Annotation(Model):
    """
    class for parsing annotation information
    """
    @classmethod
    def parse(cls, api, json):
        """parse user information"""
        annotation = cls(api)
        if json is not None:
            for k, v in json.items():
                setattr(annotation, k, v)
            return annotation
        else:
            raise APIError('Error Response!')
    
    @classmethod
    def parse_list(cls, api, json_list):
        """parse a list of annotation"""
        annotationList = []
        for json in json_list:
            annotationList.append(Annotation.parse(api, json))
        return annotationList


class Basic(Model):
    """
    class for parsing basic information
    """
    @classmethod
    def parse(cls, api, json):
        """parse unread information"""
        basic = cls(api)
        if json is not None:
            for k, v in json.items():
                setattr(basic, k, v)
            return basic
        else:
            raise APIError('Error Response!')


class Count(Model):
    """
    class for parsing count information
    """
    @classmethod
    def parse(cls, api, json):
        """parse count information"""
        count = cls(api)
        if json is not None:
            for k, v in json.items():
                setattr(count, k, v)
            return count
        else:
            raise APIError('Error Response!')

    @classmethod
    def parse_list(cls, api, json_list):
        """parse a list of count information"""
        countlist = []
        for json in json_list:
            countlist.append(Count.parse(api, json))
        return countlist


class Emotion(Model):
    """
    class for parsing emotion
    """
    @classmethod
    def parse(cls, api, json):
        """parse emotion information"""
        emotion = cls(api)
        if json is not None:
            for k, v in json.items():
                setattr(emotion, k, v)
            return emotion
        else:
            raise APIError('Error Response!')
    
    @classmethod
    def parse_list(cls, api, json_list):
        """parse a list of annotation"""
        emotionList = []
        for json in json_list:
            emotionList.append(Emotion.parse(api, json))
        return emotionList 


class Geo(Model):
    """
    class for parsing geo information
    """
    @classmethod
    def parse(cls, api, json):
        """parse geo information"""
        geo = cls(api)
        if json is not None:
            for k, v in json.items():
                setattr(geo, k, v)
            return geo
        else:
            raise APIError('Error Response!')


class Token(Model):
    """
    class for parsing token results
    """
    @classmethod
    def parse_string(cls, api, data):
        """Parse the string result"""
        token = cls(api)
        datalist = data.split('&')
        for tdata in datalist:
            pair = tdata.split('=', 1)
            setattr(token, pair[0], pair[1])
        return token


class Unread(Model):
    """
    class for parsing unread information
    """
    @classmethod
    def parse(cls, api, json):
        """parse unread information"""
        unread = cls(api)
        if json is not None:
            for k, v in json.items():
                setattr(unread, k, v)
            return unread
        else:
            raise APIError('Error Response!')


class User(Model):
    """
    class for parsing user information
    """
    @classmethod
    def parse(cls, api, json):
        """parse user information"""
        user = cls(api)
        if json is not None:
            for k, v in json.items():
                if k == 'retweeted_status':
                    if v is not None:
                        setattr(user, k, Weibo.parse(api, v))
                    else:
                        setattr(user, k, v)
                if k == 'status':
                    if v is not None:
                        setattr(user, k, Weibo.parse(api, v))
                    else:
                        setattr(user, k, v)
                if k == 'user':
                    if v is not None:
                        setattr(user, k, User.parse(api, v))
                    else:
                        setattr(user, k, v)
                else:
                    setattr(user, k, v)
            return user
        else:
            raise APIError('Error Response!')
    
    @classmethod
    def parse_list(cls, api, json_list):
        """parse a list of users"""
        userlist = []
        for json in json_list:
            userlist.append(User.parse(api, json))
        return userlist



class UserList(Model):
    """
    class for parsing user list information
    """
    @classmethod
    def parse(cls, api,json):
        """parse user list information"""
        userlist = cls(api)
        if json is not None:
            print json
            for k, v in json.items():
                if k == 'users':
                    setattr(userlist, k, User.parse_list(api, v))
                else:
                    setattr(userlist, k, v)
            return userlist
        else:
            raise APIError('Error Response!')
    
    
class Weibo(Model):
    """
    class for parsing weibo information
    """
    @classmethod
    def parse(cls, api, json):
        """parse weibo information"""
        weibo = cls(api)
        if json is not None:
            for k, v in json.items():
                if k == 'annotations':
                    setattr(weibo, k, Annotation.parse_list(api, v))
                elif k == 'user':
                    if v is not None:
                        setattr(weibo, k , User.parse(api, v))
                    else:
                        setattr(weibo, k, v)
                elif k == 'retweeted_status':
                    if v is not None:
                        setattr(weibo, k, Weibo.parse(api, v))
                    else:
                        setattr(weibo, k, v)
                elif k == 'status':
                    if v is not None:
                        setattr(weibo, k, Weibo.parse(api, v))
                    else:
                        setattr(weibo, k, v)
                elif k == 'reply_comment':
                    if v is not None:
                        setattr(weibo, k, Weibo.parse(api, v))
                    else:
                        setattr(weibo, k, v)
                elif k == 'geo':
                    if v is not None:
                        setattr(weibo, k, Geo.parse(api, v))
                    else:
                        setattr(weibo, k, v)
                else:
                    setattr(weibo, k, v)
            return weibo
        else:
            raise APIError('Error Response!')

    @classmethod
    def parse_list(cls, api, json_list):
        """parse a list of weibo"""
        weibolist = []
        for json in json_list:
            weibolist.append(Weibo.parse(api, json))
        return weibolist


class ModelFactory(object):
    """
    Used by parsers for creating instances
    of models. You may subclass this factory
    to add your own extended models.
    """
    model = Model
    basic = Basic
    count = Count
    emotion = Emotion
    token = Token
    unread = Unread
    user = User
    userlist = UserList
    weibo = Weibo
